#include "U_file.h"



int read_file(char* file_in)
{
    printf("%s\n",file_in);
    char* buffer;
    if ((buffer = getcwd(NULL,0)) == NULL)
    {
        perror("getcwd error");
    } else {
        printf("%s\n",buffer);
    }
    // FILE* file = fopen(*file_in,"r");
}
int write_csv(char* file_in,float* data_in)
{
    printf("%s\n",file_in);

    // FILE* file = 
    FILE* file = fopen(file_in,"w");
    if (file == NULL)
    {
        perror("error opening file");
        return EXIT_FAILURE;
    }
    for (int i = 0; i < 76800; i++)
    {
        fprintf(file,"%f",data_in[i]);
        if ((i+1) % 320 == 0 )
        {
            fprintf(file,",");
            fprintf(file,"\n");
        }else{
            fprintf(file,",");
        }
    }
    fclose(file);
    return 0;
}
int write_csv1(char* file_in,float* data_in,int file_len_rows,int file_len_cols)
{
    printf("%s\n",file_in);

    // FILE* file = 
    FILE* file = fopen(file_in,"w");
    if (file == NULL)
    {
        perror("error opening file");
        return EXIT_FAILURE;
    }
    for (int i = 0; i < file_len_rows * file_len_cols; i++)
    {
        fprintf(file,"%f",data_in[i]);
        if ((i+1) % file_len_cols == 0 )
        {
            fprintf(file,",");
            fprintf(file,"\n");
        }else{
            fprintf(file,",");
        }
    }
    fclose(file);
    return 0;
}



// 检查文件是否具有目标扩展名
bool is_target_type(const char *filename, const char *ext) {
    const char *dot = strrchr(filename, '.');           //从尾部开始向前查找第一次出现的'.' --> 返回位置
    if (dot && !strcasecmp(dot + 1, ext)) {             //判断字符串是否相等
        return true;
    }
    return false;
}

// 将文件路径添加到数组中
void add_file(char ***files, int *file_count, const char *file_path) {//将符合条件的文件路径添加到数组中-->(存储路径,文件个数,被存储文件路径)
    // 增加数组容量
    (*file_count)++;
    *files = realloc(*files, (*file_count) * sizeof(char *));
    if (*files == NULL) {
        perror("realloc failed");
        exit(1);
    }
    // 为新的文件路径分配内存
    (*files)[*file_count - 1] = strdup(file_path);
    if ((*files)[*file_count - 1] == NULL) {
        perror("strdup failed");
        exit(1);
    }
}

// 遍历目录并处理文件
void find_files_recursively(const char *path, const char *ext, char ***files, int *file_count) {
    DIR *dir = opendir(path);                           //打开文件路径
    if (!dir) {
        perror("opendir");
        return;
    }

    struct dirent *ep;                                  //文件信息结构体
    char current_file_path[BUFFER_SIZE];
    
    while ((ep = readdir(dir)) != NULL) {               //读目录ep
        // 跳过 . 和 ..
        if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0) {
            continue;
        }

        // 构造文件路径
        snprintf(current_file_path, BUFFER_SIZE, "%s/%s", path, ep->d_name);//文件路径构建1、2、3...

// printf("now current_file_path --> %s\n",current_file_path);//打印字符

// printf("now ep->d_name --> %s\n",ep->d_name);//打印字符

        struct stat statbuf;                            
        if (lstat(current_file_path, &statbuf) == -1) {     //获取文件属性到 statbuf 
            perror("lstat");
            continue;
        }

        if (S_ISDIR(statbuf.st_mode)) {                     //判断是否为目录
            // 如果是目录，递归查找
            find_files_recursively(current_file_path, ext, files, file_count);//-->(文件路径，搜索路径，存储路径，文件个数)
        } else if (S_ISREG(statbuf.st_mode)) {              //判断是否为文件
            // 如果是文件，检查扩展名
            if (is_target_type(ep->d_name, ext)) {               //判断是否为指定的文件类型
                add_file(files, file_count, current_file_path);  //将符合条件的文件路径添加到数组中-->(存储路径,文件个数,被存储文件路径)
            }
        }
    }
    closedir(dir);
}

int create_directory(const char* dir_path)
{
    if (mkdir(dir_path,0755) == 0)
    {
        // printf("%s success\n",dir_path); ///home/liu/Desktop/User_y/code/linux/code_study/U_c_demo/test/data/raw_out/14/
        return 0;
    } else {
        perror("mkdir file error");
        return -1;
    }
}

void delete_directory(const char *path) {
    DIR *dir = opendir(path);
    struct dirent *entry;

    if (dir == NULL) {
        perror("无法打开目录");
        return;
    }

    while ((entry = readdir(dir)) != NULL) {
        // 跳过 "." 和 ".."
        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
            continue;
        }

        char full_path[1024];
        snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name);

        struct stat statbuf;
        if (stat(full_path, &statbuf) == 0) {
            if (S_ISDIR(statbuf.st_mode)) {
                // 如果是目录，递归删除
                delete_directory(full_path);
            } else if (S_ISREG(statbuf.st_mode)) {
                // 如果是文件，直接删除
                if (remove(full_path) == 0) {
                    // printf("文件删除成功: %s\n", full_path);
                } else {
                    // perror("文件删除失败");
                }
            }
        }
    }

    closedir(dir);

    // 删除空目录
    if (rmdir(path) == 0) {
        // printf("文件夹删除成功: %s\n", path);
    } else {
        // perror("删除文件夹失败");
    }
}


int bin_rw(char* path_out,char* path_in,size_t data_lens,size_t starting_point)
{
    char file_out_all[256] = {0};
    char file_out_all_1[256] = {0};

    int j = 0;

    FILE *file_in = fopen(path_in, "rb");               //打开二进制文件
    if (file_in == NULL) {
        perror("Error opening file");
        return EXIT_FAILURE;
    }                                                   //增加判断若失败则退出

    fseek(file_in, 0, SEEK_END);                        //偏移至尾部
    long file_size = ftell(file_in);                    //返回数据流长度-->求出数据长度
    fseek(file_in, 0, SEEK_SET);                        //偏移至头部
    static int i = 0;
    
    // printf("file_size = %ld\n",file_size);

    sprintf(file_out_all,"%s%d%s",path_out,i,"/");     

// printf("%s\n",file_out_all);

delete_directory(file_out_all);                             //删除文件夹

    create_directory(file_out_all);                     //创建文件夹--> /home/liu/Desktop/User_y/code/linux/code_study/U_c_demo/test/data/raw_out/14/
//     //<*************************************************************************>
    unsigned char* buffer = (unsigned char *)malloc(data_lens);//创建空间
    if (buffer == NULL)
    {
        fclose(file_in);
        perror("error allocating memory");
        return EXIT_FAILURE;
    }

    fseek(file_in, starting_point, SEEK_SET);                        //<-------------------------------------------------------------------------------------------
    long U_file_size = ftell(file_in);                    //返回数据流长度-->求出数据长度
    // printf("output file_size = %ld\n",U_file_size);

    size_t bytes_read = fread(buffer,1,data_lens,file_in);//从file_in读数据data_lens字节长度到buffer
    if (bytes_read != data_lens)
    {
        fclose(file_in);
        free(buffer);
        perror("error reading file");
        return EXIT_FAILURE;
    }//确保读文件成功
    fclose(file_in);                                    //关闭文件
    
    sprintf(file_out_all_1,"%s%d%s%d%s",path_out,i,"/",(500 + j * 50),"_frame167_frequency1_phase.raw"); 
    j = i + 1;
    FILE* file_out = fopen(file_out_all_1,"wb");        //打开文件，文件指针file_out
    if (file_out == NULL)
    {
        free(buffer);
        perror("error opening file");
        return EXIT_FAILURE;
    }
    size_t bytes_written = fwrite(buffer,1,data_lens,file_out);     //写入文件
    if (bytes_written != data_lens)
    {
        fclose(file_out);
        free(buffer);
        perror("error writing to file");
        return EXIT_FAILURE;
    }
    // printf("write ok\n");
    fclose(file_out);
    free(buffer);
    i++;
}


/**使用说明-->
 * eg:
 * 在data/data_in文件夹下创建文件夹[0,15)
 * 会在data/data_out文件夹下创建文件夹以及分割结果
*/

int raw_transition_test(void)
{
    size_t starting_point = 0;                                                                          // 起点--> 赋初值
    /*<--------------------配置项--------------------->*/
    char *path_in = "/home/liu/Desktop/User_y/code/linux/code_study/U_c_demo/test/data/raw_in";   // 输入目录路径      
    const char *ext = "raw";                                                                            // 要查找的文件扩展名      
    char *path_out = "/home/liu/Desktop/User_y/code/linux/code_study/U_c_demo/test/data/raw_out/";      // 输出目录路径

    char path_in_all[256];

    uint8_t frame_select = 1;                                                                           // 0为上半张，1为下半张 <-----------------------
    size_t data_lens = 1280 * 243 * 4;                                                                  // 读取数据长度
    /*<---------------------------------------------->*/
    if (frame_select == 0)
    {
        starting_point = 0;
    } else if (frame_select == 1)
    {
        starting_point = 1280 * 243 * 4;
    }
    char **files = NULL;
    int file_count = 0;
    // 查找文件

    for (int i = 0; i <= 30; i++)
    {
        // strcat(path_in,i);
        sprintf(path_in_all,"%s/%d",path_in,i);
        // printf("%s\n",path_in_all);
        find_files_recursively(path_in_all, ext, &files, &file_count);                                           //-->(文件路径，搜索后缀，存储路径，文件个数)
        bin_rw(path_out,files[i],data_lens,starting_point);
        free(files[i]);                                                                                  // 释放每个文件路径的内存
    }
    free(files);                                                                                         // 释放数组的内存
    printf("raw_transition_test success\n");
    return 1;
}


/**使用说明-->
 * eg:
 * 在data/data_in文件夹下创建文件夹[0,15)
 * 会在data/data_out文件夹下创建文件夹以及分割结果
*/

int raw_transition_test1(const char *U_path_in,
                         char *U_path_out,
                         uint8_t U_frame_select,
                         size_t U_data_lens
                         )
{
    size_t starting_point = 0;                                                                          // 起点--> 赋初值
    /*<--------------------配置项--------------------->*/
    // char *path_in = "/home/liu/Desktop/User_y/code/linux/code_study/U_c_demo/test/data/raw_in";   // 输入目录路径      
    const char *ext = "raw";                                                                            // 要查找的文件扩展名      
    // char *path_out = "/home/liu/Desktop/User_y/code/linux/code_study/U_c_demo/test/data/raw_out/";      // 输出目录路径

    char path_in_all[256];

    // uint8_t frame_select = 1;                                                                           // 0为上半张，1为下半张 <-----------------------
    // size_t data_lens = 1280 * 243 * 4;                                                                  // 读取数据长度
    /*<---------------------------------------------->*/
    if (U_frame_select == 0)
    {
        starting_point = 0;
    } else if (U_frame_select == 1)
    {
        starting_point = 1280 * 243 * 4;
    }
    char **files = NULL;
    int file_count = 0;
    // 查找文件

    for (int i = 0; i <= 30; i++)
    {
        // strcat(path_in,i);
        sprintf(path_in_all,"%s/%d",U_path_in,i);
        // printf("%s\n",path_in_all);
        find_files_recursively(path_in_all, ext, &files, &file_count);                                           //-->(文件路径，搜索后缀，存储路径，文件个数)
        bin_rw(U_path_out,files[i],U_data_lens,starting_point);
        free(files[i]);                                                                                  // 释放每个文件路径的内存
    }
    free(files);                                                                                         // 释放数组的内存
    printf("raw_transition_test success\n");
    return 1;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void readCSV(const char* filename,float data[MAX_ROWS][MAX_COLS])
{
    FILE* file = fopen(filename,"r");
    if (file == NULL)
    {
        perror("Unable to open file");
        return;
    }
    char line[MAX_STR_LEN * 20];//320 --> 1280 --> 一行数据量
    // printf("%ld\n",sizeof(line));
    int row = 0;
    while (fgets(line, sizeof(line),file) && row < MAX_ROWS)
    {
        line[strcspn(line,"\n")] = 0;

        char* token = strtok(line, ",");
        int col = 0;
        while (token != NULL && col < MAX_COLS)
        {
            data[row][col] = atof(token);
            token = strtok(NULL,",");
            col++;
        }
        row++;
    }
    fclose(file);
}
void printCSV(float data[MAX_ROWS][MAX_COLS],int row, int col)
{
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            // printf("%.2f ",data[i][j]);
            printf("%f ",data[i][j]);

        }
        printf("\n");
    }
}

/// @brief 保存二维数组
/// @param filename 文件路径
/// @param data 数据流
/// @param rows 行
/// @param cols 列
void saveCSV(const char* filename, float data[MAX_ROWS][MAX_COLS], int rows, int cols)
{
    FILE* file = fopen(filename,"w");
    if(file == NULL)
    {
        perror("Unable to open file");
        return;
    }
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            // fprintf(file,"%.2f",data[i][j]);
            fprintf(file,"%f",data[i][j]);
            
            if (j < cols - 1)
            {
                fprintf(file,",");
            }
        }
        fprintf(file,"\n");
    }
    fclose(file);
}